// components/inputbox/inputbox.js

const objDepthDetect = (obj) => {
    let count = 0
    while (true) {
        var key = Object.keys(obj)[0]
        if (!obj[key]) {
            break
        }
        if (obj[key].constructor === Object) {
            count++
            obj = obj[key]
        } else if (obj[key].constructor === Array) {
            count += 2
            break
        } else {
            count += 1
            break
        }
    }
    return count
}

const multiSelectorGetRange = (dict, keys) => {
    if (!keys) keys = []
    if (keys.constructor !== Array) {
        return undefined
    }
    let depth = objDepthDetect(dict)
    let ret = new Array(depth)
    let obj = dict
    for (let i = 0; i < depth; i++) {
        if (obj.constructor === Array) {
            ret[i] = obj
            break
        } else if (obj.constructor === Object) {
            ret[i] = Object.keys(obj)
            if (keys.length - 1 < i) {
                obj = obj[Object.keys(obj)[0]]
            } else {
                obj = obj[keys[i]]
            }
        }
    }
    return ret
}

Component({
    properties: {
        title: String,
        helpText: {
            type: String,
            value: null,
            observer: function(oldval, newval, changed_path) {
                this.setData({
                    footerClass: this.data.footerClassHelp,
                    footer: newval,
                    titleColor: this.focusing ? this.properties.focusColor : this.properties.blurColor,
                    dividerColor: this.properties.blurColor,
                    subDividerColor: this.properties.focusColor
                })
            }
        },
        errorText: {
            type: String,
            value: null,
            observer: function(oldval, newval, changed_path) {
                this.setData({
                    footerClass: this.data.footerClassError,
                    footer: newval,
                    titleColor: this.data.errorColor,
                    dividerColor: this.data.errorColor,
                    subDividerColor: this.data.errorColor
                })
            }
        },
        blurColor: {
            type: String,
            value: "gray"
        },
        focusColor: {
            type: String,
            value: "rgb(33, 150, 243)"
        },
        range: null,
        mode: {
            type: String,
            value: 'selector'
        },
        value: null
    },

    data: {
        footerClassHidden: "footer-hidden",
        footerClassHelp: "footer-help",
        footerClassError: "footer-error",
        footerClass: "footer-hidden",
        footer: "",
        errorColor: "red",
        titleColor: null,
        dividerColor: null,
        subDividerColor: null,
        animationData: null,
        selectedValue: '请选择',
        columnSel: 0
    },

    attached: function() {
        this.setData({
            titleColor: this.properties.blurColor,
            dividerColor: this.properties.blurColor,
            subDividerColor: this.properties.focusColor
        })
        if (this.properties.errorText != null) {
            this.setData({
                footerClass: this.data.footerClassError,
                footer: this.properties.errorText,
                titleColor: this.data.errorColor,
                dividerColor: this.data.errorColor,
                subDividerColor: this.data.errorColor
            })
        } else if (this.properties.helpText != null) {
            this.setData({
                footerClass: this.data.footerClassHelp,
                footer: this.properties.helpText,
                titleColor: this.focusing ? this.properties.focusColor : this.properties.blurColor,
                dividerColor: this.properties.blurColor,
                subDividerColor: this.properties.focusColor
            })
        }
        this.animation = null
        this.focusing = false
        if (this.properties.mode === 'multiSelector') {
            this.rangeData = this.properties.range
            this.rangeDepth = objDepthDetect(this.rangeData)
            this.columnData = new Array(this.rangeDepth).fill(0)
            this.setData({
                columnSel: this.columnData,
                range: multiSelectorGetRange(this.rangeData, null)
            })
        }
        if (this.properties.value) {
            if (this.properties.value.constructor === Array) {
                this.setData({
                    selectedValue: this.properties.value.join(", ")
                })
            } else {
                this.setData({
                    selectedValue: this.properties.value.toString()
                })
            }
        }
    },

    methods: {
        getAnimation: function() {
            return wx.createAnimation({
                duration: 300,
                timingFunction: "ease-in-out"
            })
        },

        onFocus: function(e) {
            if (!this.animation) {
                this.animation = this.getAnimation()
            }
            this.animation.width("100%").step()
            this.setData({
                animationData: this.animation.export(),
                titleColor: this.properties.errorText ? this.data.errorColor : this.properties.focusColor
            })
            this.focusing = true
        },

        onBlur: function(e) {
            if (!this.animation) {
                return
            }
            this.animation.width("0%").step()
            this.setData({
                animationData: this.animation.export(),
                titleColor: this.properties.errorText ? this.data.errorColor : this.properties.blurColor
            })
            this.focusing = false
        },

        bindPickerChange: function(e) {
            if (this.properties.mode === 'multiSelector') {
                let displayTexts = new Array(this.rangeDepth)
                for (let i = 0; i < this.rangeDepth; i++) {
                    displayTexts[i] = this.properties.range[i][e.detail.value[i]]
                }
                this.setData({
                    selectedValue: displayTexts.join(', ')
                })
                this.triggerEvent('change', {
                    value: displayTexts
                })
            } else if (this.properties.mode === 'region') {
                this.setData({
                    selectedValue: e.detail.value.join(', ')
                })
                this.triggerEvent('change', {
                    value: e.detail.value
                })
            } else {
                this.setData({
                    selectedValue: this.properties.range[e.detail.value]
                })
                this.triggerEvent('change', {
                    value: this.properties.range[e.detail.value]
                })
            }
            this.onBlur()
        },

        bindColumnChange: function (e) {
            if (this.properties.mode !== 'multiSelector') {
                return
            }
            if (!this.rangeData) {
                return
            }
            this.columnData[e.detail.column] = e.detail.value
            let keys = new Array(this.rangeDepth)
            let obj = this.rangeData
            for (let i = 0; i < this.rangeDepth; i++) {
                keys[i] = Object.keys(obj)[this.columnData[i]]
                obj = i < this.rangeDepth ? obj[keys[i]] : null
            }
            let range = multiSelectorGetRange(this.rangeData, keys)
            this.setData({
                columnSel: this.columnData,
                range: range
            })
        }
    }
})